package com.edu.baseAndBitOperations.base;

/**
 * 位运算符的操作和理解,（左移<<、右移>>、无符号右移<<<）
 * 注意：进行位运算的时候，所有的操作数全部都是二进制，并且是补码!!!
 *
 * @作者 five-five
 * @创建时间 2021/4/16
 */
public class Demo06 {
    /*
       &：按位与，只有上下都为1的时候，才等于1
       |：按位或，只要上下有一方为1的时候，就等于1
       ^：按位异或，两个中不一样的时候才为1，如果一样就为0
       ~：按位取反，1变0,0变1
       <<：左移，让操作数乘以2的n次幂，n就是移动的位移
       >>：右移，让操作数除以2的n次幂，n就是移动的位移
       >>>：无符号右移，操作数除以2的n次幂，
       无符号右移和右移的区别是：
            右移操作之后左边会有空位置出来且空位置用该操作数的符号位置的数补全
            无符号右移之后左边会有空位置出来且空位置用0补全
       格式：操作数<<往左移动的位数
            操作数>>往右移动的位数
            操作数>>>往右移动的位数
    */
    public static void main(String[] args) {
        //左移 <<
        int i = 3;
        //3:0b00000000,00000000,00000000,00000011
        //3<<2:0b000000,00000000,00000000,0000001100(往左边移动两位，左边的两位就被挤掉了，右边就空出两位用0补全)
        System.out.println(i << 2);//3*2^2

        //右移 >>
        int j = 32;
        //32:0b00000000,00000000,00000000,00100000
        //32>>2:0b00000000,00000000,00000000,00001000(往右边移动两位，左边就空出两位，右边的两位就被挤掉了，左边空出的位置用符号位的值填充)
        System.out.println(j >> 2);//32/(2^2)

        //-32:0b10000000,00000000,00000000,00100000(原码)
        //-32:0b11111111,11111111,11111111,11011111(反码)
        //-32:0b11111111,11111111,11111111,11100000(补码)
        //-32>>2:0b11111111,11111111,11111111,11100000
        //(往右边移动两位，左边就空出两位，右边的两位就被挤掉了，左边空出的位置用符号位的值填充)
        //-32>>2:0b1111111111,11111111,11111111,111000(补码)
        //-32>>2:0b1111111111,11111111,11111111,110111(反码)
        //-32>>2:0b1000000000,00000000,00000000,001000(原码)
        System.out.println(-j >> 2);//-32/(2^2)
        System.out.println(0b11111111111111111111111111111000);//-32/(2^2)

        //无符号右移 >>>
        int k = 32;
        //32:0b00000000,00000000,00000000,00100000
        //32>>>2:0b00000000,00000000,00000000,00001000(往右边移动两位，左边就空出两位，右边的两位就被挤掉了，左边空出的位置用0填充)
        System.out.println(k >>> 2);//32/(2^2)
        //-32:0b10000000,00000000,00000000,00100000(原码)
        //-32:0b11111111,11111111,11111111,11011111(反码)
        //-32:0b11111111,11111111,11111111,11100000(补码)
        //32>>>2:0b0011111111,11111111,11111111,111000(往右边移动两位，左边就空出两位，右边的两位就被挤掉了，左边空出的位置用0填充)
        System.out.println(-k >>> 2);
        System.out.println(0b00111111111111111111111111111000);
    }
}
